package com.efrei.schoolmanager.printing;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;

import javax.swing.table.DefaultTableModel;

import com.efrei.schoolmanager.exceptions.PDFException;
import com.efrei.schoolmanager.model.ModeleBulletinNotes;
import com.efrei.schoolmanager.model.obj.Eleve;
import com.efrei.schoolmanager.model.obj.Responsable;
import com.efrei.schoolmanager.tools.Etablissement;
import com.efrei.schoolmanager.tools.Periode;
import com.itextpdf.text.BaseColor;
import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfWriter;

/**
 * Classe de generation des differents PDF
 * 
 * @author Julien
 * 
 */
public class GenerePdf {

	/**
	 * Erreur pendant la creation du fichier
	 * 
	 * @throws PDFException
	 */
	public static void createDocumentException() throws PDFException {
		throw new PDFException("Emplacement fichier invalide");
	}

	public static void generateDocumentException() throws PDFException {
		throw new PDFException(
				"Erreur pendant la génération du pdf, verifiez les données");
	}

	/**
	 * Methode de generation d'un pdf administratif (convocation,avertissement
	 * absences,certificat de scolarite,demande de bourse)
	 * 
	 * @param sujet
	 *            : le sujet
	 * @param message
	 *            : le message
	 * @param resp
	 *            : l'objet responsable permettant d'avoir ses coordonnees
	 * @param f
	 *            : le fichier à generer
	 * 
	 * @throws PDFException
	 */
	public static void generePdfAdministratif(String sujet, String message,
			Responsable resp, File f) throws PDFException {

		// Controle du fichier passe en parametre (application d'une extension
		// PDF si necessaire
		if (!f.getName().endsWith(".pdf")) {
			File f1 = new File(f.getPath() + ".pdf");
			f = f1;
		}
		Document document = new Document();

		try {
			PdfWriter.getInstance(document, new FileOutputStream(f));
		} catch (FileNotFoundException e) {
			System.err.println(e);
			createDocumentException();
		} catch (DocumentException e) {
			System.err.println(e);
			createDocumentException();
		}

		document.open();

		try {
			// Generation de l'entete de l'etablissement
			Font font1 = new Font(Font.FontFamily.TIMES_ROMAN, 15, Font.BOLD);
			Paragraph paragraph = new Paragraph(
					Etablissement.getNomEtablissement() + "\n"
							+ Etablissement.getAdresseEtablissement() + "\n"
							+ Etablissement.getVilleEtablissement(), font1);
			paragraph.setSpacingAfter(60);
			paragraph.setAlignment(Element.ALIGN_LEFT);
			document.add(paragraph);

			// Generation du destinataire du courrier
			Paragraph paragraph1 = new Paragraph(resp.getNom().toUpperCase()
					+ " " + resp.getPrenom() + "\n" + resp.getRue() + "\n"
					+ resp.getVille().getCodePostal() + " "
					+ resp.getVille().getNom(), font1);
			paragraph1.setSpacingAfter(80);
			paragraph1.setAlignment(Element.ALIGN_RIGHT);
			document.add(paragraph1);

			// Generation de l'objet
			Font font2 = new Font(Font.FontFamily.TIMES_ROMAN, 10,
					Font.UNDERLINE);
			Paragraph paragraph2 = new Paragraph();
			Chunk ch0 = new Chunk("Objet : ", font2);
			Chunk ch1 = new Chunk(sujet);
			paragraph2.add(ch0);
			paragraph2.add(ch1);
			paragraph2.setSpacingAfter(20);
			paragraph2.setAlignment(Element.ALIGN_LEFT);
			document.add(paragraph2);

			// Generation du texte
			Paragraph paragraph3 = new Paragraph(message);
			paragraph3.setSpacingAfter(10);
			document.add(paragraph3);

			// Fin generation PDF
			document.close();
		} catch (DocumentException e) {
			generateDocumentException();
		}

	}

	/**
	 * Methode de generation d'un pdf pour le bulletin d'absences
	 * 
	 * @param sujet
	 *            : le sujet
	 * @param message
	 *            : le message
	 * @param resp
	 *            : l'objet responsable permettant d'avoir ses coordonnees
	 * @param eleve
	 *            l'objet eleve permettant d'avoir son nom
	 * @param donneesTableAbsences
	 *            : les donnees de la table contenant les absences (remplis dans
	 *            la vue et non conservées en base)
	 * @param f
	 *            : le fichier à generer
	 * @throws PDFException
	 */
	public static void generePdfBulletinAbsences(String sujet, String message,
			Responsable resp, Eleve eleve,
			DefaultTableModel donneesTableAbsences, File f) throws PDFException {

		// Controle du fichier passe en parametre (application d'une extension
		// PDF si necessaire
		if (!f.getName().endsWith(".pdf")) {
			File f1 = new File(f.getPath() + ".pdf");
			f = f1;
		}
		Document document = new Document();

		try {
			PdfWriter.getInstance(document, new FileOutputStream(f));
		} catch (FileNotFoundException e) {
			System.err.println(e);
			createDocumentException();
		} catch (DocumentException e) {
			System.err.println(e);
			createDocumentException();
		}

		document.open();

		try {
			// Generation de l'entete de l'etablissement
			Font font1 = new Font(Font.FontFamily.TIMES_ROMAN, 15, Font.BOLD);
			Paragraph paragraph = new Paragraph(
					Etablissement.getNomEtablissement() + "\n"
							+ Etablissement.getAdresseEtablissement() + "\n"
							+ Etablissement.getVilleEtablissement(), font1);
			paragraph.setSpacingAfter(60);
			paragraph.setAlignment(Element.ALIGN_LEFT);
			document.add(paragraph);

			// Generation du destinataire du courrier
			Paragraph paragraph1 = new Paragraph(resp.getNom().toUpperCase()
					+ " " + resp.getPrenom() + "\n" + resp.getRue() + "\n"
					+ resp.getVille().getCodePostal() + " "
					+ resp.getVille().getNom(), font1);
			paragraph1.setSpacingAfter(100);
			paragraph1.setAlignment(Element.ALIGN_RIGHT);
			document.add(paragraph1);

			// Generation de l'objet
			Font font2 = new Font(Font.FontFamily.TIMES_ROMAN, 10,
					Font.UNDERLINE);
			Paragraph paragraph2 = new Paragraph();
			Chunk ch0 = new Chunk("Objet : ", font2);
			Chunk ch1 = new Chunk(sujet);
			paragraph2.add(ch0);
			paragraph2.add(ch1);
			paragraph2.setSpacingAfter(20);
			paragraph2.setAlignment(Element.ALIGN_LEFT);
			document.add(paragraph2);

			// Generation du texte
			Paragraph paragraph3 = new Paragraph(message);
			paragraph3.setSpacingAfter(40);
			document.add(paragraph3);

			// Generation du tableau des absences
			PdfPTable table = new PdfPTable(3);
			table.setWidthPercentage(50);
			Font font3 = new Font(Font.FontFamily.TIMES_ROMAN, 7, Font.BOLD);

			// Entetes
			PdfPCell cell1 = new PdfPCell(new Paragraph("DEBUT ABSENCE", font3));
			cell1.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell1.setFixedHeight(30);
			table.addCell(cell1);

			PdfPCell cell2 = new PdfPCell(new Paragraph("FIN ABSENCE", font3));
			cell2.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell2.setFixedHeight(30);
			table.addCell(cell2);

			PdfPCell cell3 = new PdfPCell(new Paragraph("RAISON", font3));
			cell3.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell3.setFixedHeight(30);
			table.addCell(cell3);

			// Generation des cellules pour les absences indiquees par
			// l'utilisateur
			for (int i = 0; i < donneesTableAbsences.getRowCount(); i++) {

				for (int j = 0; j < donneesTableAbsences.getColumnCount(); j++) {
					PdfPCell celltemp = new PdfPCell(new Paragraph(
							(String) donneesTableAbsences.getValueAt(i, j),
							font3));
					celltemp.setFixedHeight(15);
					table.addCell(celltemp);
				}
			}
			table.completeRow();

			document.add(table);

			// Fin generation PDF
			document.close();
		} catch (DocumentException e) {
			e.printStackTrace();
			generateDocumentException();
		}

	}

	/**
	 * Methode de generation d'un pdf de releve de Notes
	 * 
	 * @param message
	 *            : le message
	 * @param resp
	 *            : l'objet responsable permettant d'avoir ses coordonnees
	 * @param eleve
	 *            l'objet eleve permettant d'avoir son nom
	 * @param donneesTableNotes
	 *            : les donnees de la table contenant les notes
	 * @param f
	 *            : le fichier à generer
	 * @throws PDFException
	 */
	public static void generePdfReleveNotes(String message, Responsable resp,
			Eleve eleve, DefaultTableModel donneesTableNotes, File f)
			throws PDFException {

		// Controle du fichier passe en parametre (application d'une extension
		// PDF si necessaire
		if (!f.getName().endsWith(".pdf")) {
			File f1 = new File(f.getPath() + ".pdf");
			f = f1;
		}
		Document document = new Document();

		try {
			PdfWriter.getInstance(document, new FileOutputStream(f));
		} catch (FileNotFoundException e) {
			System.err.println(e);
			createDocumentException();
		} catch (DocumentException e) {
			System.err.println(e);
			createDocumentException();
		}

		document.open();

		try {
			// Generation de l'entete de l'etablissement
			Font font1 = new Font(Font.FontFamily.TIMES_ROMAN, 15, Font.BOLD);
			Paragraph paragraph = new Paragraph(
					Etablissement.getNomEtablissement() + "\n"
							+ Etablissement.getAdresseEtablissement() + "\n"
							+ Etablissement.getVilleEtablissement(), font1);
			paragraph.setSpacingAfter(60);
			paragraph.setAlignment(Element.ALIGN_LEFT);
			document.add(paragraph);

			// Generation du destinataire du courrier
			Paragraph paragraph1 = new Paragraph(resp.getNom().toUpperCase()
					+ " " + resp.getPrenom() + "\n" + resp.getRue() + "\n"
					+ resp.getVille().getCodePostal() + " "
					+ resp.getVille().getNom(), font1);
			paragraph1.setSpacingAfter(80);
			paragraph1.setAlignment(Element.ALIGN_RIGHT);
			document.add(paragraph1);

			// Generation de l'objet
			Paragraph paragraph2 = new Paragraph("Releve de Notes :");
			paragraph2.setSpacingAfter(20);
			paragraph2.setAlignment(Element.ALIGN_LEFT);
			document.add(paragraph2);

			// Generation du tableau des notes
			PdfPTable table = new PdfPTable(donneesTableNotes.getColumnCount());
			table.setWidthPercentage(95);
			Font font3 = new Font(Font.FontFamily.TIMES_ROMAN, 7, Font.BOLD);

			// Largeur des colonnes
			float[] columnWidths = new float[donneesTableNotes.getColumnCount()];
			columnWidths[0] = 5f;
			columnWidths[1] = 5f;
			columnWidths[2] = 3f;

			// Entetes
			PdfPCell cell1 = new PdfPCell(new Paragraph("Matiere", font3));
			cell1.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell1.setFixedHeight(15);
			table.addCell(cell1);

			PdfPCell cell2 = new PdfPCell(new Paragraph("Enseignant", font3));
			cell2.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell2.setFixedHeight(15);
			table.addCell(cell2);

			PdfPCell cell3 = new PdfPCell(new Paragraph("Moyenne", font3));
			cell3.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell3.setFixedHeight(15);
			table.addCell(cell3);

			// Generation des numeros de devoirs
			for (int i = 1; i < donneesTableNotes.getColumnCount() - 2; i++) {
				columnWidths[2 + i] = 2f;
				PdfPCell cellTemp = new PdfPCell(new Paragraph("Devoir " + i,
						font3));
				cellTemp.setBackgroundColor(BaseColor.LIGHT_GRAY);
				cellTemp.setFixedHeight(15);
				table.addCell(cellTemp);
			}
			table.setWidths(columnWidths);
			table.completeRow();

			// Generation des cellules contenant les notes des differents
			// devoirs
			for (int i = 0; i < donneesTableNotes.getRowCount(); i++) {
				for (int j = 0; j < donneesTableNotes.getColumnCount(); j++) {
					PdfPCell celltemp = new PdfPCell(new Paragraph(
							(String) donneesTableNotes.getValueAt(i, j), font3));
					celltemp.setFixedHeight(15);
					table.addCell(celltemp);
				}
				table.completeRow();
			}
			table.setSpacingAfter(50);
			// Ajout du tableau dans le document
			document.add(table);

			// Ajout des remarques (message du jury)
			Font font6 = new Font(Font.FontFamily.TIMES_ROMAN, 5, Font.BOLD);
			Paragraph paragraph6 = new Paragraph("Remarques du Jury :", font6);
			paragraph6.setSpacingAfter(10);
			document.add(paragraph6);

			PdfPTable table1 = new PdfPTable(1);
			table1.setWidthPercentage(95);
			PdfPCell cell16 = new PdfPCell(new Paragraph(message, font3));
			table1.addCell(cell16);
			document.add(table1);

			Font font4 = new Font(Font.FontFamily.TIMES_ROMAN, 5, Font.BOLD);
			Paragraph paragraph8 = new Paragraph(
					"Releve de notes à conserver précieusement. Aucun duplicata ne sera délivré",
					font4);
			paragraph8.setSpacingBefore(2);
			paragraph8.setIndentationLeft(12);
			document.add(paragraph8);
			document.close();

			// Fin generation PDF
			document.close();
		} catch (DocumentException e) {
			e.printStackTrace();
			generateDocumentException();
		}

	}

	/**
	 * 
	 * @param message
	 *            : le message
	 * @param resp
	 *            : l'objet responsable permettant d'avoir ses coordonnees
	 * @param eleve
	 *            l'objet eleve permettant d'avoir son nom
	 * @param donneesTableNotes
	 *            : les donnees de la table contenant les notes
	 * @param f
	 *            : le fichier à generer
	 * @param moyenneGeneraleEleve
	 *            : la moyenne Generale calculee de l'eleve
	 * @param moyenneGeneralClasse
	 *            : la moyenne Generale calculee de la classe
	 * @param avisJury
	 *            : le message avis (felicitations,encouragements etc...)
	 * @param periode
	 *            : le numero de la periode correspondante
	 * @param classe
	 *            : le nom de la classe de l'eleve
	 * @throws PDFException
	 */
	public static void generePdfBulletinNotes(String message, Responsable resp,
			Eleve eleve, ModeleBulletinNotes donneesTableNotes, File f,
			String moyenneGeneraleEleve, String moyenneGeneralClasse,
			String avisJury, Periode periode, String classe)
			throws PDFException {
		// Controle du fichier passe en parametre (application d'une extension
		// PDF si necessaire
		if (!f.getName().endsWith(".pdf")) {
			File f1 = new File(f.getPath() + ".pdf");
			f = f1;
		}
		Document document = new Document();

		try {
			PdfWriter.getInstance(document, new FileOutputStream(f));
		} catch (FileNotFoundException e1) {
			System.err.println(e1);
			createDocumentException();
		} catch (DocumentException e1) {
			System.err.println(e1);
			createDocumentException();
		}

		document.open();

		try {
			// Generation de l'entete de l'etablissement
			Font font1 = new Font(Font.FontFamily.TIMES_ROMAN, 10, Font.BOLD);
			Paragraph paragraph = new Paragraph(
					Etablissement.getNomEtablissement() + "\n"
							+ Etablissement.getAdresseEtablissement() + "\n"
							+ Etablissement.getVilleEtablissement(), font1);
			paragraph.setAlignment(Element.ALIGN_LEFT);
			document.add(paragraph);

			// Generation du texte de la classe
			Paragraph paragraph2 = new Paragraph("Classe : " + classe, font1);
			paragraph2.setSpacingAfter(20);
			paragraph2.setAlignment(Element.ALIGN_RIGHT);
			document.add(paragraph2);

			// Generation du titre du document
			Font font2 = new Font(Font.FontFamily.TIMES_ROMAN, 15, Font.BOLD);
			Paragraph paragraph3 = new Paragraph("BULLETIN PERIODE "
					+ periode.toString(), font2);
			paragraph3.setAlignment(Element.ALIGN_CENTER);
			paragraph3.setSpacingAfter(20);
			document.add(paragraph3);

			// Generation du destinataire du courrier
			Paragraph paragraph4 = new Paragraph(resp.getNom().toUpperCase()
					+ " " + resp.getPrenom() + "\n" + resp.getRue() + "\n"
					+ resp.getVille().getCodePostal() + " "
					+ resp.getVille().getNom(), font1);
			paragraph4.setSpacingAfter(30);
			paragraph4.setAlignment(Element.ALIGN_RIGHT);
			document.add(paragraph4);

			// Generation des entetes du tableau
			Font font3 = new Font(Font.FontFamily.TIMES_ROMAN, 7, Font.BOLD);
			PdfPTable table = new PdfPTable(5);

			PdfPCell cell1 = new PdfPCell(new Paragraph("MATIERES", font3));
			cell1.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell1.setFixedHeight(30);
			table.addCell(cell1);

			PdfPCell cell2 = new PdfPCell(new Paragraph("PROFESSEUR", font3));
			cell2.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell2.setFixedHeight(30);
			table.addCell(cell2);

			PdfPCell cell3 = new PdfPCell(new Paragraph("MOY ELEVE", font3));
			cell3.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell3.setFixedHeight(30);
			table.addCell(cell3);

			PdfPCell cell4 = new PdfPCell(new Paragraph("MOY CLASSE", font3));
			cell4.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell4.setFixedHeight(30);
			table.addCell(cell4);

			PdfPCell cell5 = new PdfPCell(new Paragraph("APPRECIATIONS", font3));
			cell5.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell5.setFixedHeight(20);
			table.addCell(cell5);
			table.completeRow();

			// Generation des lignes de donnes (matiere,prof,moyenne
			// eleve,moyenne classe)
			for (int i = 0; i < donneesTableNotes.getRowCount(); i++) {

				for (int j = 0; j < donneesTableNotes.getColumnCount(); j++) {
					PdfPCell celltemp1 = new PdfPCell(new Paragraph(
							(String) donneesTableNotes.getValueAt(i, j), font3));
					if (j != 4) {
						celltemp1.setFixedHeight(15);
					}
					table.addCell(celltemp1);
				}
				table.completeRow();
			}

			// Generation de la derniere ligne (moyennes generales)
			PdfPCell cell11 = new PdfPCell(new Paragraph("Moyenne Générale",
					font3));
			cell11.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell11.setFixedHeight(20);
			table.addCell(cell11);

			PdfPCell cell12 = new PdfPCell(new Paragraph("", font3));
			cell12.setFixedHeight(20);
			table.addCell(cell12);
			PdfPCell cell13 = new PdfPCell(new Paragraph(moyenneGeneraleEleve,
					font3));
			cell13.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell13.setFixedHeight(20);
			table.addCell(cell13);

			PdfPCell cell14 = new PdfPCell(new Paragraph(moyenneGeneralClasse,
					font3));
			cell14.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell14.setFixedHeight(20);
			table.addCell(cell14);

			PdfPCell cell15 = new PdfPCell(new Paragraph("", font3));
			cell15.setBackgroundColor(BaseColor.LIGHT_GRAY);
			cell15.setFixedHeight(20);
			table.addCell(cell15);

			table.setWidthPercentage(95);

			table.completeRow();

			// Largeur des colonnes
			float[] columnWidths = { 400, 400, 200, 200, 1000 };
			table.setWidths(columnWidths);

			// Ajout du tableau au document
			document.add(table);

			Paragraph paragraph5 = new Paragraph("", font1);
			paragraph5.setSpacingAfter(10);
			document.add(paragraph5);

			Paragraph paragraph6 = new Paragraph("Remarques :", font1);
			paragraph6.setSpacingAfter(10);
			document.add(paragraph6);

			// Ajout des remarques avec eventuellement un avis jury(
			// avertissement,encouragement,feliciation) si précisé
			Paragraph paragraph7 = new Paragraph(message, font3);
			if (avisJury != null) {
				Font font4 = new Font(Font.FontFamily.TIMES_ROMAN, 9, Font.BOLD);
				Paragraph paragraphe8 = new Paragraph("\n\n" + avisJury, font4);
				paragraph7.add(paragraphe8);
			}

			// Ajout des remarques dans un tableau
			PdfPTable table1 = new PdfPTable(1);
			table1.setWidthPercentage(95);
			PdfPCell cell16 = new PdfPCell(paragraph7);
			table1.addCell(cell16);
			document.add(table1);

			// Mentions legales
			Font font4 = new Font(Font.FontFamily.TIMES_ROMAN, 5, Font.BOLD);
			Paragraph paragraph8 = new Paragraph(
					"Bulletin à conserver précieusement.Aucun duplicata ne sera délivré",
					font4);
			paragraph8.setSpacingBefore(2);
			paragraph8.setIndentationLeft(12);
			document.add(paragraph8);
			document.close();
		} catch (DocumentException e) {
			e.printStackTrace();
			generateDocumentException();
		}
	}
}
